package com.tianya.common.sercurity;

import java.io.IOException;
import java.security.SecureRandom;
import java.util.Random;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import com.tianya.common.util.Utility;

/**
* 3Des安全编码组件
*
* @author 王帆
* @version 1.0.0.0
* @since 1.0.0.0
*/
public class DesCoder 
{
	private static final String defaultKey = "GbCilFJ6zQ0LXsRABCNKE63sg83ZHxaG";
	private static final String defaultIV = "544rsZRS";
	/**
	 * 加密向量用随机字符串
	 */
	private static final String CHARARRAY[] = { "0", "1", "2", "3", "4", "5",
		"6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i",
		"j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
		"w", "x", "y", "z" , "A", "B", "C", "D", "E", "F", "G", "H", "I",
		"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
		"W", "X", "Y", "Z" };
	
	/**
	 * 3DES 加密
	 * @param pContent 明文
	 * @return 密文
	 * @throws IOException
	 */
    public static String DESedeEncrypt(String pContent) throws IOException{
    	return TriDesEncrypt(Base64Coder.decodeString(defaultKey), defaultIV, pContent);		
    }
    
	/**
	 * 3DES 加密
	 * @param pKey 密钥
	 * @param pIV 加密向量
	 * @param pContent 明文
	 * @return 密文
	 * @throws IOException
	 */
    public static String DESedeEncrypt(String pKey, String pIV, String pContent) throws IOException{
    	return TriDesEncrypt(Base64Coder.decodeString(pKey), pIV, pContent);		
    }

    /**
     * 3DES 加密
     * @param pKey 密钥
     * @param pIV 加密向量
     * @param pContent pContent 明文
     * @return 密文
     */
	public static String TriDesEncrypt(String pKey, String pIV, String pContent){				
		String ret="";
		
		try
		{
			//初始化Cipher
			javax.crypto.spec.IvParameterSpec iv = new javax.crypto.spec.IvParameterSpec(pIV.getBytes());
			javax.crypto.spec.SecretKeySpec key = new javax.crypto.spec.SecretKeySpec(pKey.getBytes(),"DESede");
			javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("DESede/CBC/PKCS5Padding");
		
			//执行加密并做Base64编码
			cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key, iv);
			
			sun.misc.BASE64Encoder enc64=new sun.misc.BASE64Encoder();

			ret=enc64.encodeBuffer(cipher.doFinal(pContent.getBytes("utf-8")));
			
			return ret.replaceAll("\r\n","");
		}
		catch (Exception ex)
		{
			return "";
		}		
	}
	/**
	 * 3DES解密
	 * @param pContent 密文
	 * @return 明文
	 * @throws IOException
	 */
	public static String DESedeDecrypt(String pContent) throws IOException{	
		return TriDesDecipher(Base64Coder.decodeString(defaultKey),defaultIV,pContent);
	}
	
	/**
	 * 3DES解密
	 * @param pKey 密钥
	 * @param pIV 向量
	 * @param pContent 密文
	 * @return 明文
	 * @throws IOException
	 */
	public static String DESedeDecrypt(String pKey, String pIV, String pContent) throws IOException{	
		
		return TriDesDecipher(Base64Coder.decodeString(pKey),pIV,pContent);
	}
	/**
	 * 3DES解密
	 * @param pKey 密钥
	 * @param pIV 向量
	 * @param pContent 密文
	 * @return 明文
	 */
	public static String TriDesDecipher(String pKey, String pIV, String pContent){	
		
		try
		{
			//初始化Cipher
			javax.crypto.spec.IvParameterSpec iv = new javax.crypto.spec.IvParameterSpec(pIV.getBytes());
			javax.crypto.spec.SecretKeySpec key = new javax.crypto.spec.SecretKeySpec(pKey.getBytes(),"DESede");
			javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("DESede/CBC/PKCS5Padding");
		
			//执行Base64还原并解密
			sun.misc.BASE64Decoder enc64=new sun.misc.BASE64Decoder();
			cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key, iv);
			byte[] rest= cipher.doFinal(enc64.decodeBuffer(pContent));
			return new String(rest,"UTF-8");
		}
		catch (Exception ex)
		{
			return "";
		}		
	}

	/**
	 * RSA加密 【环迅支付用】
	 * @param pKey RSA密钥
	 * @param pContent  加密明文
	 * @return 密文
	 */
	public static String RSAEncrypt(String pKey, String pContent)			
	{				
		String ret="";
		
		try
		{
			//解析密钥得到公钥和系数
			int startIndex=pKey.indexOf("<Modulus>")+9;
			int endIndex=pKey.indexOf("</Modulus>");		
			
			byte[] b=new sun.misc.BASE64Decoder().decodeBuffer(pKey.substring(startIndex, endIndex));
			
			String N=Utility.Bin2HexString(b);
			
			startIndex=pKey.indexOf("<Exponent>")+10;
			endIndex=pKey.indexOf("</Exponent>");
			
			b=new sun.misc.BASE64Decoder().decodeBuffer(pKey.substring(startIndex, endIndex));
			
			String E=Utility.Bin2HexString(b);
			
			//初始化Cipher
			java.math.BigInteger bigN=new java.math.BigInteger(N,16);
			java.math.BigInteger bigE=new java.math.BigInteger(E,16);						
			java.security.spec.RSAPublicKeySpec pubSpec=new java.security.spec.RSAPublicKeySpec(bigN,bigE);			
			javax.crypto.Cipher cipher=javax.crypto.Cipher.getInstance("RSA/ECB/PKCS1Padding");			
			
			//执行加密并做Base64编码
			cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, java.security.KeyFactory.getInstance("RSA").generatePublic(pubSpec));					
			
			sun.misc.BASE64Encoder enc64=new sun.misc.BASE64Encoder();
			
			ret=enc64.encodeBuffer(cipher.doFinal(pContent.getBytes("utf-8")));
			
			return ret.replaceAll("\r\n","");
		}
		catch (Exception ex)
		{
			return "";
		}		
	}
	
	/**
	 * 获取3DES加密密钥
	 * @return 密钥
	 */
	public static String createDESedeKey() { 
		try{ 
		KeyGenerator generator = KeyGenerator.getInstance("DESede"); 
		generator.init(new SecureRandom()); 
		SecretKey key = generator.generateKey(); 
		return Base64Coder.encodeString(key.getEncoded());
		} 
		catch(Exception ex) { 
			System.out.print( "ERROR:" + ex.getMessage()); 
		}
		return null;
	}

	/**
	 * 获取3DES加密向量
	 * @return 加密向量
	 */
	public static String createDESedeIv() { 
		// 生成随机类    
		Random random = new Random();  
		// 取随机产生的字符串 
		String sRand="";    
		int total = 8;
		for (int i=0;i<total;i++){    
			String rand = CHARARRAY[random.nextInt(CHARARRAY.length)];
			sRand+=rand;  
		}   
		return sRand;
	}
	
	
	/**
	 * 获取供应商的3DES加密密钥
	 * @return 密钥
	 * @throws IOException 
	 */
	public static String createDESKey() throws IOException { 
		// 生成随机类    
		Random random = new Random();  
		// 取随机产生的字符串 
		String sRand="";    
		int total = 8;
		for (int i=0;i<total;i++){    
			String rand = CHARARRAY[random.nextInt(CHARARRAY.length)];
			sRand+=rand;  
		} 
		return Base64Coder.encodeString(sRand);
	}
	
	/**
	 * 3DES 供应商加密
	 * @param pKey 密钥
	 * @param pIV 加密向量
	 * @param pContent 明文
	 * @return 密文
	 * @throws IOException
	 */
    public static String Encrypt(String pKey, String pIV, String pContent) throws IOException{
    	return DesEncrypt(Base64Coder.decodeString(pKey), pIV, pContent);		
    }

    /**
     * 3DES 加密
     * @param pKey 密钥
     * @param pIV 加密向量
     * @param pContent pContent 明文
     * @return 密文
     */
	public static String DesEncrypt(String pKey, String pIV, String pContent){				
		String ret="";
		
		try
		{
			//初始化Cipher
			javax.crypto.spec.IvParameterSpec iv = new javax.crypto.spec.IvParameterSpec(pIV.getBytes());
			javax.crypto.spec.SecretKeySpec key = new javax.crypto.spec.SecretKeySpec(pKey.getBytes(),"DES");
			javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("DES/CBC/PKCS5Padding");
		
			//执行加密并做Base64编码
			cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key, iv);
			
			sun.misc.BASE64Encoder enc64=new sun.misc.BASE64Encoder();

			ret=enc64.encodeBuffer(cipher.doFinal(pContent.getBytes("utf-8")));
			
			return ret.replaceAll("\r\n","");
		}
		catch (Exception ex)
		{
			return "";
		}		
	}
	/**
	 * 3DES解密
	 * @param pKey 密钥
	 * @param pIV 向量
	 * @param pContent 密文
	 * @return 明文
	 * @throws IOException
	 */
	public static String Decrypt(String pKey, String pIV, String pContent) throws IOException{	
		
		return DesDecipher(Base64Coder.decodeString(pKey),pIV,pContent);
	}
	/**
	 * 3DES解密
	 * @param pKey 密钥
	 * @param pIV 向量
	 * @param pContent 密文
	 * @return 明文
	 */
	public static String DesDecipher(String pKey, String pIV, String pContent){	
		
		try
		{
			//初始化Cipher
			javax.crypto.spec.IvParameterSpec iv = new javax.crypto.spec.IvParameterSpec(pIV.getBytes());
			javax.crypto.spec.SecretKeySpec key = new javax.crypto.spec.SecretKeySpec(pKey.getBytes(),"DES");
			javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("DES/CBC/PKCS5Padding");
		
			//执行Base64还原并解密
			sun.misc.BASE64Decoder enc64=new sun.misc.BASE64Decoder();
			cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key, iv);
			byte[] rest= cipher.doFinal(enc64.decodeBuffer(pContent));
			return new String(rest,"UTF-8");
		}
		catch (Exception ex)
		{
			return "";
		}		
	}
	

}
